package com.hxht.cmp.websocket;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.hxht.cmp.entity.User;
import com.hxht.cmp.mapper.UserMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;


@ServerEndpoint(value = "/vodWebSocket", configurator = SpringConfigurator.class)
public class VodWebSocket {
    private Logger logger = LoggerFactory.getLogger(VodWebSocket.class);
    @Resource
    private UserMapper userMapper;

    private static final List<Session> sessions;
    private static List<Map<String, String>> cmpPlayList;
    private static Map<String, Map<String, String>> VOD_USER_MAP;

    static {
        sessions = new ArrayList<>();
        VOD_USER_MAP = new HashMap<>();
        cmpPlayList = Collections.synchronizedList(new ArrayList<>());
    }


    @OnMessage
    public void onMessage(String message, Session session) throws IOException, InterruptedException {
        if ("HeartBeat".equals(message)||message.contains("ws")) {
            return;
        }
        Map<String, String> obj = new Gson().fromJson(message, new TypeToken<Map<String, String>>() {
        }.getType());
        String userName = obj.get("userName");
        String planUid = obj.get("planUid");
        String type = obj.get("type");
        String archives = obj.get("archives");
        String name = obj.get("name");
        String vod = obj.get("vod");
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String, String> recordPlay = new HashMap<>();
        recordPlay.put("uid", session.getId());
        recordPlay.put("caseUid", obj.get("caseUid"));
        recordPlay.put("planUid", planUid);
        recordPlay.put("type", type);
        recordPlay.put("archives", archives);
        recordPlay.put("name", name);
        recordPlay.put("vod", vod);
        recordPlay.put("startTime", format.format(new Date()));
        try {
            recordPlay.put("userCourtUid", obj.get("userCourtUid"));
            User user = new User();
            user.setUsername(userName);
            if (!Objects.equals("super", userName)) {
                user.setCourtUid(obj.get("userCourtUid"));
            }
            user = userMapper.selectOne(user);
            recordPlay.put("id", user.getId().toString());
            recordPlay.put("userName", user.getUsername());
            recordPlay.put("realName", user.getRealName());
            recordPlay.put("userUid", user.getUid());
        } catch (Exception e) {
            logger.error("websocket 获取用户异常,message:" + e.getMessage());
        }
        VOD_USER_MAP.put(session.getId(), recordPlay);
        cmpPlayList.add(recordPlay);
    }

    @OnOpen
    public void onOpen(Session session) {
        sessions.add(session);
        System.out.println("Connection build");
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("Connection closed");
        sessions.remove(session);
        VOD_USER_MAP.remove(session.getId());
        //这里要使用Iterator的remove方法移除当前对象，如果使用List的remove方法，则同样会出现ConcurrentModificationException
        cmpPlayList.removeIf(record -> Objects.deepEquals(session.getId(), record.get("uid")));
    }

    @OnError
    public void onError(Session session, Throwable error) {
        Map<String, String> map = VOD_USER_MAP.get(session.getId());
        if (!ObjectUtils.isEmpty(map)) {
            logger.error(map.get("id") + "_username:" + map.get("userName") + "session error ,message: " + error.getMessage());
        } else {
            logger.error("session error ,message: " + error.getMessage());
        }
    }

    public static void sendMessage(String message) throws IOException {
        for (Session session : sessions) {
            session.getBasicRemote().sendText(message);//同步
        }
    }

    public static void messageLock(String message, String userId) throws IOException {
        for (Map.Entry<String, Map<String, String>> entry : VOD_USER_MAP.entrySet()) {
            if (entry.getValue().get("userUid").equals(userId)) {
                for (Session session : sessions) {
                    if (entry.getKey().equals(session.getId())) {
                        session.getBasicRemote().sendText(message);//同步
                    }
                }
            }

        }
    }

    public static List<JsonObject> selectVodUser() {
        List<JsonObject> list = new ArrayList<>();
        VOD_USER_MAP.forEach((k, v) -> {
            JsonObject object = new JsonObject();
            object.addProperty("caseUid", v.get("caseUid"));
            object.addProperty("planUid", v.get("planUid"));
            object.addProperty("archives", v.get("archives"));
            object.addProperty("name", v.get("name"));
            object.addProperty("type", v.get("type"));
            object.addProperty("vod", v.get("vod"));
            object.addProperty("userCourtUid", v.get("userCourtUid"));
            object.addProperty("id", v.get("id"));
            object.addProperty("userName", v.get("userName"));
            object.addProperty("userUid", v.get("userUid"));
            object.addProperty("realName", v.get("realName"));
            list.add(object);
        });
        return list;
    }

    public static List<Map<String, String>> getCmpPlayList() {
        return cmpPlayList;
    }
}
